<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="generator" content="AsciiDoc 8.5.2" />
<title></title>
<style type="text/css">
/* Debug borders */
p, li, dt, dd, div, pre, h1, h2, h3, h4, h5, h6 {
/*
  border: 1px solid red;
*/
}

body {
  margin: 1em 5% 1em 5%;
}

a {
  color: blue;
  text-decoration: underline;
}
a:visited {
  color: fuchsia;
}

em {
  font-style: italic;
  color: navy;
}

strong {
  font-weight: bold;
  color: #083194;
}

tt {
  color: navy;
}

h1, h2, h3, h4, h5, h6 {
  color: #527bbd;
  font-family: sans-serif;
  margin-top: 1.2em;
  margin-bottom: 0.5em;
  line-height: 1.3;
}

h1, h2, h3 {
  border-bottom: 2px solid silver;
}
h2 {
  padding-top: 0.5em;
}
h3 {
  float: left;
}
h3 + * {
  clear: left;
}

div.sectionbody {
  font-family: serif;
  margin-left: 0;
}

hr {
  border: 1px solid silver;
}

p {
  margin-top: 0.5em;
  margin-bottom: 0.5em;
}

ul, ol, li > p {
  margin-top: 0;
}

pre {
  padding: 0;
  margin: 0;
}

span#author {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  font-size: 1.1em;
}
span#email {
}
span#revnumber, span#revdate, span#revremark {
  font-family: sans-serif;
}

div#footer {
  font-family: sans-serif;
  font-size: small;
  border-top: 2px solid silver;
  padding-top: 0.5em;
  margin-top: 4.0em;
}
div#footer-text {
  float: left;
  padding-bottom: 0.5em;
}
div#footer-badges {
  float: right;
  padding-bottom: 0.5em;
}

div#preamble {
  margin-top: 1.5em;
  margin-bottom: 1.5em;
}
div.tableblock, div.imageblock, div.exampleblock, div.verseblock,
div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
div.admonitionblock {
  margin-top: 1.0em;
  margin-bottom: 1.5em;
}
div.admonitionblock {
  margin-top: 2.0em;
  margin-bottom: 2.0em;
  margin-right: 10%;
  color: #606060;
}

div.content { /* Block element content. */
  padding: 0;
}

/* Block element titles. */
div.title, caption.title {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  text-align: left;
  margin-top: 1.0em;
  margin-bottom: 0.5em;
}
div.title + * {
  margin-top: 0;
}

td div.title:first-child {
  margin-top: 0.0em;
}
div.content div.title:first-child {
  margin-top: 0.0em;
}
div.content + div.title {
  margin-top: 0.0em;
}

div.sidebarblock > div.content {
  background: #ffffee;
  border: 1px solid silver;
  padding: 0.5em;
}

div.listingblock > div.content {
  border: 1px solid silver;
  background: #f4f4f4;
  padding: 0.5em;
}

div.quoteblock, div.verseblock {
  padding-left: 1.0em;
  margin-left: 1.0em;
  margin-right: 10%;
  border-left: 5px solid #dddddd;
  color: #777777;
}

div.quoteblock > div.attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock > div.content {
  white-space: pre;
}
div.verseblock > div.attribution {
  padding-top: 0.75em;
  text-align: left;
}
/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
div.verseblock + div.attribution {
  text-align: left;
}

div.admonitionblock .icon {
  vertical-align: top;
  font-size: 1.1em;
  font-weight: bold;
  text-decoration: underline;
  color: #527bbd;
  padding-right: 0.5em;
}
div.admonitionblock td.content {
  padding-left: 0.5em;
  border-left: 3px solid #dddddd;
}

div.exampleblock > div.content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

div.imageblock div.content { padding-left: 0; }
span.image img { border-style: none; }
a.image:visited { color: white; }

dl {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
dt {
  margin-top: 0.5em;
  margin-bottom: 0;
  font-style: normal;
  color: navy;
}
dd > *:first-child {
  margin-top: 0.1em;
}

ul, ol {
    list-style-position: outside;
}
ol.arabic {
  list-style-type: decimal;
}
ol.loweralpha {
  list-style-type: lower-alpha;
}
ol.upperalpha {
  list-style-type: upper-alpha;
}
ol.lowerroman {
  list-style-type: lower-roman;
}
ol.upperroman {
  list-style-type: upper-roman;
}

div.compact ul, div.compact ol,
div.compact p, div.compact p,
div.compact div, div.compact div {
  margin-top: 0.1em;
  margin-bottom: 0.1em;
}

div.tableblock > table {
  border: 3px solid #527bbd;
}
thead, p.table.header {
  font-family: sans-serif;
  font-weight: bold;
}
tfoot {
  font-weight: bold;
}
td > div.verse {
  white-space: pre;
}
p.table {
  margin-top: 0;
}
/* Because the table frame attribute is overriden by CSS in most browsers. */
div.tableblock > table[frame="void"] {
  border-style: none;
}
div.tableblock > table[frame="hsides"] {
  border-left-style: none;
  border-right-style: none;
}
div.tableblock > table[frame="vsides"] {
  border-top-style: none;
  border-bottom-style: none;
}


div.hdlist {
  margin-top: 0.8em;
  margin-bottom: 0.8em;
}
div.hdlist tr {
  padding-bottom: 15px;
}
dt.hdlist1.strong, td.hdlist1.strong {
  font-weight: bold;
}
td.hdlist1 {
  vertical-align: top;
  font-style: normal;
  padding-right: 0.8em;
  color: navy;
}
td.hdlist2 {
  vertical-align: top;
}
div.hdlist.compact tr {
  margin: 0;
  padding-bottom: 0;
}

.comment {
  background: yellow;
}

.footnote, .footnoteref {
  font-size: 0.8em;
}

span.footnote, span.footnoteref {
  vertical-align: super;
}

#footnotes {
  margin: 20px 0 20px 0;
  padding: 7px 0 0 0;
}

#footnotes div.footnote {
  margin: 0 0 5px 0;
}

#footnotes hr {
  border: none;
  border-top: 1px solid silver;
  height: 1px;
  text-align: left;
  margin-left: 0;
  width: 20%;
  min-width: 100px;
}


@media print {
  div#footer-badges { display: none; }
}

div#toc {
  margin-bottom: 2.5em;
}

div#toctitle {
  color: #527bbd;
  font-family: sans-serif;
  font-size: 1.1em;
  font-weight: bold;
  margin-top: 1.0em;
  margin-bottom: 0.1em;
}

div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
  margin-top: 0;
  margin-bottom: 0;
}
div.toclevel2 {
  margin-left: 2em;
  font-size: 0.9em;
}
div.toclevel3 {
  margin-left: 4em;
  font-size: 0.9em;
}
div.toclevel4 {
  margin-left: 6em;
  font-size: 0.9em;
}
/* Workarounds for IE6's broken and incomplete CSS2. */

div.sidebar-content {
  background: #ffffee;
  border: 1px solid silver;
  padding: 0.5em;
}
div.sidebar-title, div.image-title {
  color: #527bbd;
  font-family: sans-serif;
  font-weight: bold;
  margin-top: 0.0em;
  margin-bottom: 0.5em;
}

div.listingblock div.content {
  border: 1px solid silver;
  background: #f4f4f4;
  padding: 0.5em;
}

div.quoteblock-attribution {
  padding-top: 0.5em;
  text-align: right;
}

div.verseblock-content {
  white-space: pre;
}
div.verseblock-attribution {
  padding-top: 0.75em;
  text-align: left;
}

div.exampleblock-content {
  border-left: 3px solid #dddddd;
  padding-left: 0.5em;
}

/* IE6 sets dynamically generated links as visited. */
div#toc a:visited { color: blue; }
</style>
<script type="text/javascript">
/*<![CDATA[*/
window.onload = function(){asciidoc.footnotes();}
var asciidoc = {  // Namespace.

/////////////////////////////////////////////////////////////////////
// Table Of Contents generator
/////////////////////////////////////////////////////////////////////

/* Author: Mihai Bazon, September 2002
 * http://students.infoiasi.ro/~mishoo
 *
 * Table Of Content generator
 * Version: 0.4
 *
 * Feel free to use this script under the terms of the GNU General Public
 * License, as long as you do not remove or alter this notice.
 */

 /* modified by Troy D. Hanson, September 2006. License: GPL */
 /* modified by Stuart Rackham, 2006, 2009. License: GPL */

// toclevels = 1..4.
toc: function (toclevels) {

  function getText(el) {
    var text = "";
    for (var i = el.firstChild; i != null; i = i.nextSibling) {
      if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
        text += i.data;
      else if (i.firstChild != null)
        text += getText(i);
    }
    return text;
  }

  function TocEntry(el, text, toclevel) {
    this.element = el;
    this.text = text;
    this.toclevel = toclevel;
  }

  function tocEntries(el, toclevels) {
    var result = new Array;
    var re = new RegExp('[hH]([2-'+(toclevels+1)+'])');
    // Function that scans the DOM tree for header elements (the DOM2
    // nodeIterator API would be a better technique but not supported by all
    // browsers).
    var iterate = function (el) {
      for (var i = el.firstChild; i != null; i = i.nextSibling) {
        if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
          var mo = re.exec(i.tagName);
          if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
            result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
          }
          iterate(i);
        }
      }
    }
    iterate(el);
    return result;
  }

  var toc = document.getElementById("toc");
  var entries = tocEntries(document.getElementById("content"), toclevels);
  for (var i = 0; i < entries.length; ++i) {
    var entry = entries[i];
    if (entry.element.id == "")
      entry.element.id = "_toc_" + i;
    var a = document.createElement("a");
    a.href = "#" + entry.element.id;
    a.appendChild(document.createTextNode(entry.text));
    var div = document.createElement("div");
    div.appendChild(a);
    div.className = "toclevel" + entry.toclevel;
    toc.appendChild(div);
  }
  if (entries.length == 0)
    toc.parentNode.removeChild(toc);
},


/////////////////////////////////////////////////////////////////////
// Footnotes generator
/////////////////////////////////////////////////////////////////////

/* Based on footnote generation code from:
 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
 */

footnotes: function () {
  var cont = document.getElementById("content");
  var noteholder = document.getElementById("footnotes");
  var spans = cont.getElementsByTagName("span");
  var refs = {};
  var n = 0;
  for (i=0; i<spans.length; i++) {
    if (spans[i].className == "footnote") {
      n++;
      // Use [\s\S] in place of . so multi-line matches work.
      // Because JavaScript has no s (dotall) regex flag.
      note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
      noteholder.innerHTML +=
        "<div class='footnote' id='_footnote_" + n + "'>" +
        "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
        n + "</a>. " + note + "</div>";
      spans[i].innerHTML =
        "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
        "' title='View footnote' class='footnote'>" + n + "</a>]";
      var id =spans[i].getAttribute("id");
      if (id != null) refs["#"+id] = n;
    }
  }
  if (n == 0)
    noteholder.parentNode.removeChild(noteholder);
  else {
    // Process footnoterefs.
    for (i=0; i<spans.length; i++) {
      if (spans[i].className == "footnoteref") {
        var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
        href = href.match(/#.*/)[0];  // Because IE return full URL.
        n = refs[href];
        spans[i].innerHTML =
          "[<a href='#_footnote_" + n +
          "' title='View footnote' class='footnote'>" + n + "</a>]";
      }
    }
  }
}

}
/*]]>*/
</script>
</head>
<body>
<div id="header">
</div>
<div id="content">

<h2 id="_creating_an_event_base">Creating an event_base</h2>
<div class="sectionbody">
<div class="paragraph"><p>Before you can use any interesting Libevent function, you need to allocate
one or more event_base structures.  Each event_base structure holds a set of
events and can poll to determine which events are active.</p></div>
<div class="paragraph"><p>If an event_base is set up to use locking, it is safe to access it between
multiple threads.  Its loop can only be run in a single thread, however.  If
you want to have multiple threads polling for IO, you need to have an
event_base for each thread.</p></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Tip</div>
</td>
<td class="content">[A future version of Libevent may have support for event_bases that run
events across multiple threads.]</td>
</tr></table>
</div>
<div class="paragraph"><p>Each event_base has a "method", or a backend that it uses to determine which
events are ready.  The recognized methods are:</p></div>
<div class="ulist"><ul>
<li>
<p>
select
</p>
</li>
<li>
<p>
poll
</p>
</li>
<li>
<p>
epoll
</p>
</li>
<li>
<p>
kqueue
</p>
</li>
<li>
<p>
devpoll
</p>
</li>
<li>
<p>
evport
</p>
</li>
<li>
<p>
win32
</p>
</li>
</ul></div>
<div class="paragraph"><p>The user can disable specific backends with environment variables.  If you
want to turn off the kqueue backend, set the EVENT_NOKQUEUE environment
variable, and so on.  If you want to turn off backends from within the
program, see notes on event_config_avoid_method() below.</p></div>
<h3 id="_setting_up_a_default_event_base">Setting up a default event_base</h3><div style="clear:left"></div>
<div class="paragraph"><p>The event_base_new() function allocates and returns a new event base with
the default settings.  It examines the environment variables and returns
a pointer to a new event_base.  If there is an error, it returns NULL.</p></div>
<div class="paragraph"><p>When choosing among methods, it picks the fastest method that the OS
supports.</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>struct</strong> event_base *event_base_new(<strong>void</strong>);</tt></pre>
</div></div>
<div class="paragraph"><p>For most programs, this is all you need.</p></div>
<div class="paragraph"><p>The event_base_new() function is declared in &lt;event2/event.h&gt;.  It first
appeared in Libevent 1.4.3.</p></div>
<h3 id="_setting_up_a_complicated_event_base">Setting up a complicated event_base</h3><div style="clear:left"></div>
<div class="paragraph"><p>If you want more control over what kind of event_base you get, you need to
use an event_config.  An event_config is an opaque structure that holds
information about your preferences for an event_base.  When you want an
event_base, you pass the event_config to event_base_new_with_config().</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>struct</strong> event_config *event_config_new(<strong>void</strong>);
<strong>struct</strong> event_base *event_base_new_with_config(<strong>const</strong> <strong>struct</strong> event_config *cfg);
<strong>void</strong> event_config_free(<strong>struct</strong> event_config *cfg);</tt></pre>
</div></div>
<div class="paragraph"><p>To allocate an event_base with these functions, you call event_config_new()
to allocate a new event_config.  Then, you call other functions on the
event_config to tell it about your needs.  Finally, you call
event_base_new_with_config() to get a new event_base.  When you are done,
you can free the event_config with event_config_free().</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>int</strong> event_config_avoid_method(<strong>struct</strong> event_config *cfg, <strong>const</strong> <strong>char</strong> *method);

<strong>enum</strong> event_method_feature {
    EV_FEATURE_ET = 0x01,
    EV_FEATURE_O1 = 0x02,
    EV_FEATURE_FDS = 0x04,
};
<strong>int</strong> event_config_require_features(<strong>struct</strong> event_config *cfg,
                                  <strong>enum</strong> event_method_feature feature);

<strong>enum</strong> event_base_config_flag {
    EVENT_BASE_FLAG_NOLOCK = 0x01,
    EVENT_BASE_FLAG_IGNORE_ENV = 0x02,
    EVENT_BASE_FLAG_STARTUP_IOCP = 0x04,
    EVENT_BASE_FLAG_NO_CACHE_TIME = 0x08,
    EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST = 0x10,
    EVENT_BASE_FLAG_PRECISE_TIMER = 0x20
};
<strong>int</strong> event_config_set_flag(<strong>struct</strong> event_config *cfg,
    <strong>enum</strong> event_base_config_flag flag);</tt></pre>
</div></div>
<div class="paragraph"><p>Calling event_config_avoid_method tells Libevent to avoid a specific
available backend by name.  Calling event_config_require_feature() tells
Libevent not to use any backend that cannot supply all of a set of features.
Calling event_config_set_flag() tells Libevent to set one or more of
the run-time flags below when constructing the event base.</p></div>
<div class="paragraph"><p>The recognized feature values for event_config_require_features are:</p></div>
<div class="dlist"><dl>
<dt class="hdlist1">
EV_FEATURE_ET
</dt>
<dd>
<p>
    Requires a backend method that supports edge-triggered IO.
</p>
</dd>
<dt class="hdlist1">
EV_FEATURE_O1
</dt>
<dd>
<p>
    Requires a backend method where adding or deleting a single
    event, or having a single event become active, is an O(1) operation.
</p>
</dd>
<dt class="hdlist1">
EV_FEATURE_FDS
</dt>
<dd>
<p>
    Requires a backend method that can support arbitrary file
    descriptor types, and not just sockets.
</p>
</dd>
</dl></div>
<div class="paragraph"><p>The recognized option values for event_config_set_flag() are:</p></div>
<div class="dlist"><dl>
<dt class="hdlist1">
EVENT_BASE_FLAG_NOLOCK
</dt>
<dd>
<p>
    Do not allocate locks for the event_base. Setting
    this option may save a little time for locking and releasing the
    event_base, but will make it unsafe and nonfunctional to access it
    from multiple threads.
</p>
</dd>
<dt class="hdlist1">
EVENT_BASE_FLAG_IGNORE_ENV
</dt>
<dd>
<p>
    Do not check the EVENT_* environment
    variables when picking which backend method to use.  Think hard before
    using this flag: it can make it harder for users to debug the interactions
    between your program and Libevent.
</p>
</dd>
<dt class="hdlist1">
EVENT_BASE_FLAG_STARTUP_IOCP
</dt>
<dd>
<p>
    On Windows only, this flag makes Libevent
    enable any necessary IOCP dispatch logic on startup, rather than
    on-demand.
</p>
</dd>
<dt class="hdlist1">
EVENT_BASE_FLAG_NO_CACHE_TIME
</dt>
<dd>
<p>
    Instead of checking the current time every
    time the event loop is ready to run timeout callbacks, check it after
    every timeout callback.  This can use more CPU than you necessarily
    intended, so watch out!
</p>
</dd>
<dt class="hdlist1">
EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST
</dt>
<dd>
<p>
    Tells Libevent that, if it decides to
    use the epoll backend, it is safe to use the faster "changelist"-based
    backend.  The epoll-changelist backend can avoid needless system calls in
    cases where the same fd has its status modified more than once between
    calls to the backend&#8217;s dispatch function, but it also trigger a kernel bug
    that causes erroneous results if you give Libevent any fds cloned by
    dup() or its variants.  This flag has no effect if you use a backend
    other than epoll.  You can also turn on the epoll-changelist option by
    setting the EVENT_EPOLL_USE_CHANGELIST environment variable.
</p>
</dd>
<dt class="hdlist1">
EVENT_BASE_FLAG_PRECISE_TIMER
</dt>
<dd>
<p>
    By default, Libevent tries to use the fastest available timing mechanism
    that the operating system provides.  If there is a slower timing
    mechanism that provides more fine-grained timing precision, this
    flag tells Libevent to use that timing mechanism instead.  If the
    operating system provides no such slower-but-more-precise mechanism,
    this flag has no effect.
</p>
</dd>
</dl></div>
<div class="paragraph"><p>The above functions that manipulate an event_config all return 0 on success,
-1 on failure.</p></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">It is easy to set up an event_config that requires a backend that your
OS does not provide.  For example, as of Libevent 2.0.1-alpha, there is no
O(1) backend for Windows, and no backend on Linux that provides both
EV_FEATURE_FDS and EV_FEATURE_O1.  If you have made a configuration that
Libevent can&#8217;t satisfy, event_base_new_with_config() will return NULL.</td>
</tr></table>
</div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>int</strong> event_config_set_num_cpus_hint(<strong>struct</strong> event_config *cfg, <strong>int</strong> cpus)</tt></pre>
</div></div>
<div class="paragraph"><p>This function is currently only useful with Windows when using IOCP, though
it may become useful for other platforms in the future.  Calling it tells the
event_config that the event_base it generates should try to make good use of
a given number of CPUs when multithreading.  Note that this is only a hint:
the event base may wind up using more or fewer CPUs than you select.</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>int</strong> event_config_set_max_dispatch_interval(<strong>struct</strong> event_config *cfg,
    <strong>const</strong> <strong>struct</strong> timeval *max_interval, <strong>int</strong> max_callbacks,
    <strong>int</strong> min_priority);</tt></pre>
</div></div>
<div class="paragraph"><p>This function prevents priority inversion by limiting how many low-priority
event callbacks can be invoked before checking for more high-priority events.
If max_interval is non-null, the event loop checks the time after each
callback, and re-scans for high-priority events if max_interval has passed.
If max_callbacks is nonnegative, the event loop also checks for more events
after max_callbacks callbacks have been invoked.  These rules apply to any
event of min_priority or higher.</p></div>
<div class="listingblock">
<div class="title">Example: Preferring edge-triggered backends</div>
<div class="content">
<pre><tt><strong>struct</strong> event_config *cfg;
<strong>struct</strong> event_base *base;
<strong>int</strong> i;

<i>/* My program wants to use edge-triggered events if at all possible.  So</i>
<i>   I'll try to get a base twice: Once insisting on edge-triggered IO, and</i>
<i>   once not. */</i>
<strong>for</strong> (i=0; i&lt;2; ++i) {
    cfg = event_config_new();

<i>    /* I don't like select. */</i>
    event_config_avoid_method(cfg, "select");

    <strong>if</strong> (i == 0)
        event_config_require_features(cfg, EV_FEATURE_ET);

    base = event_base_new_with_config(cfg);
    event_config_free(cfg);
    <strong>if</strong> (base)
        <strong>break</strong>;

<i>    /* If we get here, event_base_new_with_config() returned NULL.  If</i>
<i>       this is the first time around the loop, we'll try again without</i>
<i>       setting EV_FEATURE_ET.  If this is the second time around the</i>
<i>       loop, we'll give up. */</i>
}</tt></pre>
</div></div>
<div class="listingblock">
<div class="title">Example: Avoiding priority-inversion</div>
<div class="content">
<pre><tt><strong>struct</strong> event_config *cfg;
<strong>struct</strong> event_base *base;

cfg = event_config_new();
<strong>if</strong> (!cfg)
<i>   /* Handle error */;</i>

<i>/* I'm going to have events running at two priorities.  I expect that</i>
<i>   some of my priority-1 events are going to have pretty slow callbacks,</i>
<i>   so I don't want more than 100 msec to elapse (or 5 callbacks) before</i>
<i>   checking for priority-0 events. */</i>
<strong>struct</strong> timeval msec_100 = { 0, 100*1000 };
event_config_set_max_dispatch_interval(cfg, &amp;msec_100, 5, 1);

base = event_base_new_with_config(cfg);
<strong>if</strong> (!base)
<i>   /* Handle error */;</i>

event_base_priority_init(base, 2);</tt></pre>
</div></div>
<div class="paragraph"><p>These functions and types are declared in &lt;event2/event.h&gt;.</p></div>
<div class="paragraph"><p>The EVENT_BASE_FLAG_IGNORE_ENV flag first appeared in Libevent 2.0.2-alpha.
The EVENT_BASE_FLAG_PRECISE_TIMER flag first appeared in Libevent
2.1.2-alpha. The  event_config_set_num_cpus_hint() function was new in Libevent
2.0.7-rc, and event_config_set_max_dispatch_interval() was new in 2.1.1-alpha.
Everything else in this section first appeared in Libevent 2.0.1-alpha.</p></div>
<h3 id="_examining_an_event_base_8217_s_backend_method">Examining an event_base&#8217;s backend method</h3><div style="clear:left"></div>
<div class="paragraph"><p>Sometimes you want to see which features are actually available in an
event_base, or which method it&#8217;s using.</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>const</strong> <strong>char</strong> **event_get_supported_methods(<strong>void</strong>);</tt></pre>
</div></div>
<div class="paragraph"><p>The event_get_supported_methods() function returns a pointer to an array of
the names of the methods supported in this version of Libevent.  The
last element in the array is NULL.</p></div>
<div class="listingblock">
<div class="title">Example</div>
<div class="content">
<pre><tt><strong>int</strong> i;
<strong>const</strong> <strong>char</strong> **methods = event_get_supported_methods();
printf("Starting Libevent %s.  Available methods are:\n",
    event_get_version());
<strong>for</strong> (i=0; methods[i] != NULL; ++i) {
    printf("    %s\n", methods[i]);
}</tt></pre>
</div></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">This function returns a list of the methods that Libevent was compiled
to support.  It is possible that your operating system will not in fact
support them all when Libevent tries to run.  For example, you could be on a
version of OSX where kqueue is too buggy to use.</td>
</tr></table>
</div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>const</strong> <strong>char</strong> *event_base_get_method(<strong>const</strong> <strong>struct</strong> event_base *base);
<strong>enum</strong> event_method_feature event_base_get_features(<strong>const</strong> <strong>struct</strong> event_base *base);</tt></pre>
</div></div>
<div class="paragraph"><p>The event_base_get_method() call returns the name of the actual method in use
by an event_base.  The event_base_get_features() call returns a bitmask of
the features that it supports.</p></div>
<div class="listingblock">
<div class="title">Example</div>
<div class="content">
<pre><tt><strong>struct</strong> event_base *base;
<strong>enum</strong> event_method_feature f;

base = event_base_new();
<strong>if</strong> (!base) {
    puts("Couldn't get an event_base!");
} <strong>else</strong> {
    printf("Using Libevent with backend method %s.",
        event_base_get_method(base));
    f = event_base_get_features(base);
    <strong>if</strong> ((f &amp; EV_FEATURE_ET))
        printf("  Edge-triggered events are supported.");
    <strong>if</strong> ((f &amp; EV_FEATURE_O1))
        printf("  O(1) event notification is supported.");
    <strong>if</strong> ((f &amp; EV_FEATURE_FDS))
        printf("  All FD types are supported.");
    puts("");
}</tt></pre>
</div></div>
<div class="paragraph"><p>These functions are defined in &lt;event2/event.h&gt;.  The event_base_get_method()
call was first available in Libevent 1.4.3.  The others first appeared in
Libevent 2.0.1-alpha.</p></div>
<h3 id="_deallocating_an_event_base">Deallocating an event_base</h3><div style="clear:left"></div>
<div class="paragraph"><p>When you are finished with an event_base, you can deallocate it with
event_base_free().</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>void</strong> event_base_free(<strong>struct</strong> event_base *base);</tt></pre>
</div></div>
<div class="paragraph"><p>Note that this function does not deallocate any of the events that are
currently associated with the event_base, or close any of their sockets, or
free any of their pointers.</p></div>
<div class="paragraph"><p>The event_base_free() function is defined in &lt;event2/event.h&gt;. It was first
implemented in Libevent 1.2.</p></div>
<h3 id="_setting_priorities_on_an_event_base">Setting priorities on an event_base</h3><div style="clear:left"></div>
<div class="paragraph"><p>Libevent supports setting multiple priorities on an event.  By default,
though, an event_base supports only a single priority level.  You can set the
number of priorities on an event_base by calling event_base_priority_init().</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>int</strong> event_base_priority_init(<strong>struct</strong> event_base *base, <strong>int</strong> n_priorities);</tt></pre>
</div></div>
<div class="paragraph"><p>This function returns 0 on success and -1 on failure.  The <em>base</em> argument is
the event_base to modify, and n_priorities is the number of priorities to
support.  It must be at least 1.  The available priorities for new events
will be numbered from 0 (most important) to n_priorities-1 (least important).</p></div>
<div class="paragraph"><p>There is a constant, EVENT_MAX_PRIORITIES, that sets the upper bound on the
value of n_priorities.  It is an error to call this function with a higher
value for n_priorities.</p></div>
<div class="admonitionblock">
<table><tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">You <strong>must</strong> call this function before any events become active.  It is
best to call it immediately after creating the event_base.</td>
</tr></table>
</div>
<div class="paragraph"><p>To find the number of priorities currently supported by a base, you can
call event_base_getnpriorities().</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>int</strong> event_base_get_npriorities(<strong>struct</strong> event_base *base);</tt></pre>
</div></div>
<div class="paragraph"><p>The return value is equal to the number of priorities configured in the
base.  So if event_base_get_npriorities() returns 3, then allowable priority
values are 0, 1, and 2.</p></div>
<div class="listingblock">
<div class="title">Example</div>
<div class="content">
<pre><tt>For an example, see the documentation for event_priority_set below.</tt></pre>
</div></div>
<div class="paragraph"><p>By default, all new events associated with this base will be initialized
with priority equal to n_priorities / 2.</p></div>
<div class="paragraph"><p>The event_base_priority_init function is defined in &lt;event2/event.h&gt;.  It has
been available since Libevent 1.0.  The event_base_get_npriorities() function
was new in Libevent 2.1.1-alpha.</p></div>
<h3 id="_reinitializing_an_event_base_after_fork">Reinitializing an event_base after fork()</h3><div style="clear:left"></div>
<div class="paragraph"><p>Not all event backends persist cleanly after a call to fork().  Thus, if your
program uses fork() or a related system call in order to start a new process,
and you want to continue using an event_base after you have forked, you may
need to reinitialize it.</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>int</strong> event_reinit(<strong>struct</strong> event_base *base);</tt></pre>
</div></div>
<div class="paragraph"><p>The function returns 0 on success, -1 on failure.</p></div>
<div class="listingblock">
<div class="title">Example</div>
<div class="content">
<pre><tt><strong>struct</strong> event_base *base = event_base_new();

<i>/* ... add some events to the event_base ... */</i>

<strong>if</strong> (fork()) {
<i>    /* In parent */</i>
    continue_running_parent(base); /*...*/
} <strong>else</strong> {
<i>    /* In child */</i>
    event_reinit(base);
    continue_running_child(base); /*...*/
}</tt></pre>
</div></div>
<div class="paragraph"><p>The event_reinit() function is defined in &lt;event2/event.h&gt;. It was first
available in Libevent 1.4.3-alpha.</p></div>
<h3 id="_obsolete_event_base_functions">Obsolete event_base functions</h3><div style="clear:left"></div>
<div class="paragraph"><p>Older versions of Libevent relied pretty heavily on the idea of a
"current" event_base.  The "current" event_base was a global setting
shared across all threads.  If you forgot to specify which event_base
you wanted, you got the current one.  Since event_bases weren&#8217;t
threadsafe, this could get pretty error-prone.</p></div>
<div class="paragraph"><p>Instead of event_base_new(), there was:</p></div>
<div class="listingblock">
<div class="title">Interface</div>
<div class="content">
<pre><tt><strong>struct</strong> event_base *event_init(<strong>void</strong>);</tt></pre>
</div></div>
<div class="paragraph"><p>This function worked like event_base_new(), and set the current base
to the allocated base.  There was no other way to change the
current base.</p></div>
<div class="paragraph"><p>Some of the event_base functions in this section had variants that
operated on the current base.  These functions behaved as the current
functions, except that they took no base argument.</p></div>
<div class="tableblock">
<table rules="all"
width="85%"
frame="border"
cellspacing="0" cellpadding="4">
<col width="50%" />
<col width="50%" />
<thead>
<tr>
<th align="left" valign="top"> Current function              </th>
<th align="left" valign="top"> Obsolete current-base version</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" valign="top"><p class="table">event_base_priority_init()</p></td>
<td align="left" valign="top"><p class="table">event_priority_init()</p></td>
</tr>
<tr>
<td align="left" valign="top"><p class="table">event_base_get_method()</p></td>
<td align="left" valign="top"><p class="table">event_get_method()</p></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div id="footnotes"><hr /></div>
<div id="footer">
<div id="footer-text">
Last updated 2012-11-18 19:34:24 EDT
</div>
</div>
</body>
</html>
